#ifndef CTRL_PROJECT_CONTROLLER_HPP
#define CTRL_PROJECT_CONTROLLER_HPP

#include "Ctrl/CtrlConfig.hpp"
#include "Model/Project.hpp"
#include "Storage/StorageFactory.hpp"
#include <boost/signal.hpp>

namespace Ctrl
{

/// @ingroup Ctrl
/// @brief It provides the signals to announce various events related to project operations on the model.
/// @warning This class has the ownership of the current project and the associated storage factory!
class CTRL_API ProjectController
{
	typedef Model::Project Project;

public:
	typedef boost::signal< void ( const Project&)> ProjectSlot;
	typedef boost::signal< void ( Project*)> ProjectChangedSlot;

public:
	/// @brief It initializes the controller.
	/// @param pControlledProject the project that is controlled through this controller.
	explicit ProjectController( Project* pControlledProject = NULL);

public: // Slot subscriptions
	/// @brief It binds the specified slot to the project description changed signal.
	void subscribeToProjectDescriptionChange( const ProjectSlot::slot_type& slot);
	/// @brief It binds the specified slot to the project changed signal.
	void subscribeToProjectChanged( const ProjectChangedSlot::slot_type& slot);

public: // Logic operations
	/// @brief It changes the controlled project and announces it through signaling the project change event.
	void setControlledProject( Project* pNewCtrledProject, Storage::StorageFactory* pNewStorageFactory);

	/// @brief It checks whether the controlled project is valid (not NULL).
	bool hasControlledProject() const { return NULL != pControlledProject_.get(); }

	/// @brief It gets the controlled project.
	/// @pre There is a valid controlled project.
	/// @{
	const Project& controlledProject() const { return *pControlledProject_; }
	Project& controlledProject() { return *pControlledProject_; }
	/// @}

	/// @brief It gets the storage factory associated with this project.
	Storage::StorageFactory& storageFactory() { return *pStorageFactory_; }

private:
	std::auto_ptr< Model::Project> pControlledProject_;
	std::auto_ptr< Storage::StorageFactory> pStorageFactory_;

private: // Slots
	ProjectSlot onProjectDescriptionChange_;
	ProjectChangedSlot onProjectChanged_;
};

} // namespace CaseCtrl

#endif // CTRL_PROJECT_CONTROLLER_HPP
